﻿using Nanolink;
using NanolinkDemo;
using System.Collections;
using UnityEngine;
using UnityEngine.Events;

namespace CoverShooter
{
    /// <summary>
    /// Takes player input and translates that to commands to CharacterMotor.
    /// </summary>
    [RequireComponent(typeof(CharacterMotor))]
    public class ThirdPersonInput : MonoBehaviour
    {
        [HideInInspector]
        public byte m_PlayerNumber;
        [HideInInspector]
        public GameObject m_Instance;
        /// <summary>
        /// Camera mooved by this input component.
        /// </summary>
        public ThirdPersonCamera Camera
        {
            get
            {
                if (CameraOverride != null)
                    return CameraOverride;
                else
                {
                    if (CameraManager.Main != _cachedCameraOwner)
                    {
                        _cachedCameraOwner = CameraManager.Main;

                        if (_cachedCameraOwner == null)
                            _cachedCamera = null;
                        else
                            _cachedCamera = _cachedCameraOwner.GetComponent<ThirdPersonCamera>();
                    }

                    return _cachedCamera;
                }
            }
        }

        /// <summary>
        /// Camera to rotate around the player. If set to none it is taken from the main camera.
        /// </summary>
        [Tooltip("Camera to rotate around the player. If set to none it is taken from the main camera.")]
        public ThirdPersonCamera CameraOverride;

        /// <summary>
        /// Multiplier for horizontal camera rotation.
        /// </summary>
        [Tooltip("Multiplier for horizontal camera rotation.")]
        [Range(0, 10)]
        public float HorizontalRotateSpeed = 0.9f;

        /// <summary>
        /// Multiplier for vertical camera rotation.
        /// </summary>
        [Tooltip("Multiplier for vertical camera rotation.")]
        [Range(0, 10)]
        public float VerticalRotateSpeed = 1.0f;

        /// <summary>
        /// Is camera responding to mouse movement when the mouse cursor is unlocked.
        /// </summary>
        [Tooltip("Is camera responding to mouse movement when the mouse cursor is unlocked.")]
        public bool RotateWhenUnlocked = false;

        /// <summary>
        /// Maximum time in seconds to wait for a second tap to active rolling.
        /// </summary>
        [Tooltip("Maximum time in seconds to wait for a second tap to active rolling.")]
        public float DoubleTapDelay = 0.3f;

        public CharacterMotor _motor;
        public ThirdPersonController _controller;

        private Camera _cachedCameraOwner;
        private ThirdPersonCamera _cachedCamera;

        public float _timeW;
        public float _timeA;
        public float _timeS;
        public float _timeD;

        public bool isOnline;
        int playerIndex = -1;
        public bool isLead;


        [HideInInspector]
        public UnityEvent m_moveEvent;

        private void Awake()
        {
            if (m_moveEvent == null)
            {
                m_moveEvent = new UnityEvent();
            }

            _controller = GetComponent<ThirdPersonController>();
            _motor = GetComponent<CharacterMotor>();
        }
        

        void Start()
        {
            string subname = name.Substring(name.Length - 1);
            playerIndex = int.Parse(subname);
        }

        private void Update()
        {
            /*UpdateCamera();
            UpdateTarget();
            UpdateWeapons();
            UpdateReload();
            UpdateRolling();
            UpdateFireAndZoom();
            UpdateGrenade();
            UpdateCrouching();
            UpdateClimbing();
            UpdateCover();
            UpdateJumping();*/
        }
        
        bool StopUpdateMove = true;
        

        public virtual void UpdateClimbing()
        {
            if (Input.GetAxis("Vertical") > 0.1f)
                if (_motor.IsInCover && _motor.CanClimbOrVault)
                    _motor.InputClimbOrVault();
        }

        protected virtual void UpdateCover()
        {
            if (Input.GetButtonDown("TakeCover"))
                if (!_controller.AutoTakeCover && !_motor.IsInCover && _motor.PotentialCover != null)
                    _motor.InputTakeCover();
        }

        

        protected virtual void UpdateCrouching()
        {
            if (!_motor.IsSprinting && Input.GetButton("Crouch"))
                _motor.InputCrouch();
        }

        protected virtual void UpdateGrenade()
        {
            if (_motor.HasGrenadeInHand)
            {
                if (Input.GetButtonDown("Fire1"))
                    _controller.InputThrowGrenade();

                if (Input.GetButtonDown("Fire2"))
                    _motor.InputCancelGrenade();

                if (!_motor.IsReadyToThrowGrenade)
                    if (Input.GetButton("Grenade"))
                        _motor.InputTakeGrenade();
            }
            else
            {
                if (Input.GetButton("Grenade"))
                    _motor.InputTakeGrenade();
            }
        }

        public virtual void UpdateJumping(float _jumpAngle)
        {
            print("ssssfdsfsdf");
            _motor.OtherInputJump(_jumpAngle);
        }

        public virtual void UpdateRolling(float _rollAngle)
        {
            if (_motor.IsInCover && _motor.CanClimbOrVault)
                _motor.InputClimbOrVault();
            else                    
                _motor.OtherInputRoll(_rollAngle);
        }
        

        protected virtual void UpdateReload()
        {
            if (!_motor.HasGrenadeInHand)
                if (Input.GetButton("Reload"))
                    _motor.InputReload();
        }

        protected virtual void UpdateTarget()
        {
            if (_controller == null)
                return;

            var camera = Camera;
            if (camera == null) return;

            var lookPosition = camera.transform.position + camera.transform.forward * 1000;

            _controller.LookTargetInput = lookPosition;
            _controller.GrenadeHorizontalAngleInput = Util.AngleOfVector(camera.transform.forward);
            _controller.GrenadeVerticalAngleInput = Mathf.Asin(camera.transform.forward.y) * 180f / Mathf.PI;

            var closestHit = Util.GetClosestHit(camera.transform.position, lookPosition, Vector3.Distance(camera.transform.position, _motor.Top), gameObject);

            if (_motor.TurnSettings.IsAimingPrecisely)
                closestHit += transform.forward;

            _controller.FireTargetInput = closestHit;
        }

        protected virtual void UpdateCamera()
        {
            var camera = Camera;
            if (camera == null) return;

            if (Cursor.lockState == CursorLockMode.Locked || RotateWhenUnlocked)
            {
                var scale = 1.0f;

                if (_controller.IsZooming && _motor != null && _motor.Gun != null)
                    scale = 1.0f - _motor.Gun.Zoom / camera.StateFOV;

                camera.Horizontal = Mathf.LerpAngle(camera.Horizontal, camera.Horizontal + Input.GetAxis("Mouse X") * HorizontalRotateSpeed * Time.timeScale * scale, 1.0f);
                camera.Vertical = Mathf.LerpAngle(camera.Vertical, camera.Vertical - Input.GetAxis("Mouse Y") * VerticalRotateSpeed * Time.timeScale * scale, 1.0f);
                camera.UpdatePosition();
            }
        }
    }
}